iT邦幫忙

2022 iThome 鐵人賽

DAY 14
2
Modern Web

Laravel 9 漫遊,享受魔法般的極速網頁開發體驗系列 第 14

Day 14:另一種管理權限的方式:談 Laravel Gate

  • 分享至 

  • xImage
  •  

做完文章的系統,以及自動化測試之後,我們要開始允許用戶撰寫文章了。

[Day 22] 實作用戶權限!談 Laravel Policy 這篇文章裡面,我們提到了如何用 Laravel Policy 來協助我們管理文章編輯的權限。

其實,Laravel 還提供另一種管理權限的方式,而且比起 Laravel Policy 要更簡單!這個做法就是標題所說的 Laravel Gate

今天我們就來學看看怎麼使用 Laravel Gate

什麼是 Laravel Gate

根據官方的說明

Laravel provides two primary ways of authorizing actions: gates and policies. Think of gates and policies like routes and controllers. Gates provide a simple, closure-based approach to authorization while policies, like controllers, group logic around a particular model or resource.

簡單的說,比起功能比較完整的 Laravel Policy,Laravel Gate 可以提供比較容易撰寫,但是功能相對單純的權限管理。

要撰寫 gate,我們要先定義在 App\Providers\AuthServiceProvider  裡面的 boot() 裡面:

use App\Models\Post;
use App\Models\User;
use Illuminate\Support\Facades\Gate;
 
/**
 * Register any authentication / authorization services.
 *
 * @return void
 */
public function boot()
{
    $this->registerPolicies();
 
    Gate::define('update-post', function (User $user, Post $post) {
        return $user->id === $post->user_id;
    });
}

當然,如果你想沿用已經撰寫好的 Policy,也是可以的

use App\Policies\PostPolicy;
use Illuminate\Support\Facades\Gate;
 
/**
 * Register any authentication / authorization services.
 *
 * @return void
 */
public function boot()
{
    $this->registerPolicies();
 
    Gate::define('update-post', [PostPolicy::class, 'update']);
}

定義好了之後,我們就可以任意地在 controller 內使用這個 gate

if (! Gate::allows('update-post', $post)) {
	abort(403);
}

就這樣!是不是很簡單呢?

你也可以宣告一個會回傳特定回應的 gate

use App\Models\User;
use Illuminate\Auth\Access\Response;
use Illuminate\Support\Facades\Gate;

Gate::define('edit-settings', function (User $user) {
    return $user->isAdmin
                ? Response::allow()
                : Response::deny('You must be an administrator.');
});

這樣就可以客製化自己希望的回傳內容了。

除了客製化內容,你也可以客製化回傳的 HTTP action

use App\Models\User;
use Illuminate\Auth\Access\Response;
use Illuminate\Support\Facades\Gate;
 
Gate::define('edit-settings', function (User $user) {
    return $user->isAdmin
                ? Response::allow()
                : Response::denyWithStatus(418);// I am a teapot
});

如果你只是想回傳單純的 404,還可以寫得更加語意化

use App\Models\User;
use Illuminate\Auth\Access\Response;
use Illuminate\Support\Facades\Gate;
 
Gate::define('edit-settings', function (User $user) {
    return $user->isAdmin
                ? Response::allow()
                : Response::denyAsNotFound();
});

在某些狀況,你可能會覺得註冊 gate 還是太麻煩了,希望可以有更簡單的用法,Laravel 還可以這樣寫

use Illuminate\Support\Facades\Gate;
 
Gate::allowIf(fn ($user) => $user->isAdministrator());

這樣一來,如果用戶不是 Administrator 的話,Laravel 就會自動拋出 AuthorizationException,變成回傳的時候就會自動變成 403 Forbidden 了!是不是很方便呢?

今天有關權限的分享就到這邊。各位明天見!


上一篇
Day 13:用 Factory 協助資料庫的自動化測試
下一篇
Day 15:更單純的加解密:談 Laravel 9 的 Accessor 和 Mutator
系列文
Laravel 9 漫遊,享受魔法般的極速網頁開發體驗30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言